package e3dds

import (
	"gitee.com/ameise84/e3dds/internal/log"
	"gitee.com/ameise84/e3log"
	"time"

	"gitee.com/ameise84/e3dds/internal/discov"
	"gitee.com/ameise84/e3dds/internal/message"
	"gitee.com/ameise84/e3dds/internal/rpc"
)

func init() {
	rpc.SetRpcMsgPostFunc(_gRouterProvider.post)
}

func SetLogger(l *e3log.Logger) {
	log.SetLogger(l)
}

func RegisterNetService(srvID string, fac ActorFactory, msgSize int32) (NetService, error) {
	opts := DefaultServiceOptions()
	opts.SetMode(BLModePoll)
	opts.SetMsgSize(msgSize)
	return _gRouterProvider.register(true, srvID, fac, opts)
}

func RegisterRpcService(srvID string, fac ActorFactory, opts *ServiceOptions) (RpcService, error) {
	return _gRouterProvider.register(false, srvID, fac, opts)
}

func Start(opts *DcsOptions) (err error) {
	message.SetCallSlowDuration(time.Duration(opts.callSlow) * time.Second)
	_gCallTimeOut = time.Duration(opts.callTimeOut) * time.Second
	//启动服务与发现
	if err = discov.Start(opts.discoOptions); err != nil {
		return err
	}
	defer func() {
		if err != nil {
			discov.Stop()
		}
	}()
	//启动rpc服务
	var rpcAddr string
	if rpcAddr, err = rpc.Start(opts.rpcOptions); err != nil {
		return err
	}
	defer func() {
		if err != nil {
			rpc.Stop()
		}
	}()
	//启动本地服务展厅
	return _gRouterProvider.start(rpcAddr)
}

func Stop() {
	_gRouterProvider.stop()
	rpc.Stop()
	discov.Stop()
}

func BroadcastToService(srvID string, protoc string, body []byte) {
	msg := message.TakeMessage()
	msg.SetKind(message.MsgBroadcastToService)
	msg.SetToActor(srvID, "", "")
	msg.SetMsg(protoc, body)
	_gRouterProvider.broadcast(srvID, msg)
}

func BroadcastToActor(srvID string, protoc string, body []byte) {
	msg := message.TakeMessage()
	msg.SetKind(message.MsgBroadcastToActor)
	msg.SetToActor(srvID, "", "")
	msg.SetMsg(protoc, body)
	_gRouterProvider.broadcast(srvID, msg)
}

func TakeMessage() Message {
	return message.TakeMessage()
}

func FreeMessage(msg Message) {
	message.FreeMessage(msg.(*message.Msg))
}

func TakeResponse() Response {
	return message.TakeMessage()
}

func FreeResponse(rsp Response) {
	message.FreeMessage(rsp.(*message.Msg))
}

func SourceFromJson(js string) (*Source, error) {
	s := message.Source{}
	err := s.FromJson(js)
	return &s, err
}
